#include "puzzle.h"

//private
void puzzle::swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
	draw();
}

bool puzzle::checkWin(){
	int count = 1;
	for (int i = 0; i < board.size(); i++)
	{
		for (int j = 0; j < board[i].size(); j++)
		{
			if (board[i][j] != count){
				return false;
			}
			count = ++count % 16;
		}
		
	}
	return true;
}


//public
void puzzle::draw()
{
	system("cls");
	for (int i = 0; i < board.size(); i++)
	{
		//draw line div |==================|
		cout << "|";
		for (int j = 0; j < board[i].size() * 5 - 1; j++)
		{
			cout << "=";
		}
		cout << "|" << endl;

		//draw number tiles separated by " | "
		cout << "|";
		for (int j = 0; j < board[i].size(); j++)
		{	
			if (board[i][j] == 0)
				cout << "    |";
			else
				cout << " " << setw(2) << right << board[i][j] << " |";
		}
		cout << endl;
	}

	//draw final line div |==================|
	cout << "|";
	for (int j = 0; j < board[0].size() * 5 - 1; j++)
	{
		cout << "=";
	}
	cout << "|" << endl;
}

void puzzle::play()
{
	const char KEY_LEFT = 75;
	const char KEY_RIGHT = 77;
	const char KEY_UP = 72;
	const char KEY_DOWN = 80;

	draw();
	while (!checkWin())
	{
		char input = _getch();
		switch (input)
		{
		case KEY_LEFT:
			if (x > 0){
				swap(board[y][x], board[y][x--]);
			}
			break;
		case KEY_RIGHT:
			if (x < board[0].size() - 1)
			{
				swap(board[y][x], board[y][x++]);
			}
			break;
		case KEY_UP:
			if (y > 0){
				swap(board[y][x], board[y--][x]);
			}
			break;
		case KEY_DOWN:
			if (y < board.size() - 1)
			{
				swap(board[y][x], board[y++][x]);
			}
		default:
			break;
		}
	}
	cout << "You Win!!!!!!" << endl;
}


//constructor
puzzle::puzzle()
{
	bool puzzle_is_solvable = false;

	//create vector of numbers 0-15
	srand(time(NULL));
	vector<int> tiles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

	while (!puzzle_is_solvable)
	{
		//shuffle the vector
		random_shuffle(tiles.begin(), tiles.end());

		//check if vector is solvable
		int sum = 0;
		for (int i = 0; i < tiles.size(); i++)
		{
			if (tiles[i] > 0){
				for (int j = i + 1; j < tiles.size(); j++)
				{
					if (tiles[j] < tiles[i]){
						sum += tiles[j];
					}
				}
			}
			else {
				switch (i){
				case 0:
					sum += 6;
					break;
				case 1:
					sum += 5;
					break;
				case 2:
					sum += 4;
					break;
				case 3:
					sum += 3;
					break;
				case 4:
					sum += 5;
					break;
				case 5:
					sum += 4;
					break;
				case 6:
					sum += 3;
					break;
				case 7:
					sum += 2;
					break;
				case 8:
					sum += 4;
					break;
				case 9:
					sum += 3;
					break;
				case 10:
					sum += 2;
					break;
				case 11:
					sum++;
					break;
				case 12:
					sum += 3;
					break;
				case 13:
					sum += 2;
					break;
				case 14:
					sum++;
					break;
				default:
					break;
				}
			}
		}
		if (sum % 2 == 1){
			puzzle_is_solvable = true;
		}
	}

	//create 4x4 board
	board = vector<vector<int>>(4);
	for (int i = 0; i < board.size(); i++)
	{
		board[i] = vector<int>(4);
	}

	//fill board with the randomized numbers from vector tiles
	//also find position of number 0 (player starting position)
	int k = 0;
	for (int i = 0; i < board.size(); i++)
	{
		for (int j = 0; j < board[i].size(); j++)
		{
			board[i][j] = tiles[k];
			if (tiles[k] == 0)
			{
				x = j;
				y = i;
			}
			k++;
		}
	}
}


//destructor
puzzle::~puzzle()
{
}


